package ltd.hxya.novel.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import ltd.hxya.novel.admin.entity.Notice;
import ltd.hxya.novel.admin.entity.Operation;
import ltd.hxya.novel.admin.mapper.NoticeMapper;
import ltd.hxya.novel.admin.service.INoticeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ltd.hxya.novel.admin.service.IOperationService;
import ltd.hxya.novel.common.constant.ParamsConstant;
import ltd.hxya.novel.common.constant.rabbit.RabbitConstant;
import ltd.hxya.novel.common.utils.BaseUtils;
import ltd.hxya.novel.common.utils.PageUtils;
import ltd.hxya.novel.common.vo.PageParam;
import ltd.hxya.novel.common.anno.RabbitAck;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hty
 * @since 2022-10-08
 */
@Service
@Slf4j
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements INoticeService {

    @Autowired
    private INoticeService noticeService;

    @Autowired
    private NoticeMapper noticeMapper;

    @Autowired
    private IOperationService operationService;

    @RabbitListener(bindings = @QueueBinding(
                    value = @Queue(RabbitConstant.ADMIN_NOTICE_QUEUE),
                    exchange = @Exchange(RabbitConstant.ADMIN_NOTICE_EXCHANGE),
                    key = RabbitConstant.ADMIN_NOTICE_ROUTING_KEY))
    @RabbitHandler
    @RabbitAck
    public void saveNotice(Notice notice, Message message, Channel channel) throws IOException {

        //操作数据库，将notice信息保存到数据库中
        notice.setCreateTime(LocalDateTime.now());
        noticeService.save(notice);
        //TODO 使用@RabbitAck不生效，不能自动确认
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        channel.basicAck(deliveryTag,true);
    }


    @Override
    public Page<Notice> noticeList(Notice notice) {
        QueryWrapper<Notice> noticeQueryWrapper = new QueryWrapper<>();
        if (notice.getStatus()!=null){
            noticeQueryWrapper.eq("status",notice.getStatus());
        }
        BaseUtils.compareTime(noticeQueryWrapper,notice);
        PageParam pageParams = PageUtils.getPageParams();
        Page<Notice> noticePage = this.page(new Page<>(pageParams.getCurrent(), pageParams.getSize()), noticeQueryWrapper);

        //重新开启一个线程，将当前查询到的通知集合的状态修改成已读

        CompletableFuture.runAsync(()->{
           changeStatus(noticePage);
        });
        return noticePage;
    }

    @Override
    public Page<Notice> notRead() {
        QueryWrapper<Notice> noticeQueryWrapper = new QueryWrapper<>();
        noticeQueryWrapper.eq("status",false);
        PageParam pageParams = PageUtils.getPageParams();
        Notice notice = new Notice();
        Map<String,Object> map = new LinkedHashMap<>();
        map.put(ParamsConstant.END_TIME,LocalDateTime.now().toString());
        LocalDate endDate = LocalDate.of(LocalDate.now().getYear(), LocalDate.now().getMonth(), LocalDate.now().getDayOfMonth() - 3);
        map.put(ParamsConstant.BEGIN_TIME,LocalDateTime.of(endDate, LocalTime.now()).toString());
        notice.setParams(map);
        BaseUtils.compareTime(noticeQueryWrapper,notice);
        Page<Notice> noticePage = this.page(new Page<Notice>(pageParams.getCurrent(), pageParams.getSize()), noticeQueryWrapper);
        return noticePage;
    }

    @Override
    public void deleteNotice(String[] noticeIds) {
        //如果noticeIds为null，则清空所有的通知
        if (noticeIds==null){
            baseMapper.delete(null);
            return;
        }
        if (noticeIds.length<=0){
            return;
        }
        List<String> noticeIdList = Arrays.asList(noticeIds);
        baseMapper.deleteBatchIds(noticeIdList);
    }

    @Override
    public void deleteNotice() {
        deleteNotice(null);
    }

    /**
     * 查询通知的详情信息，根据notice中的模块key查询出模块的path
     * @param notice
     */
    @Override
    public String detailInfo(Notice notice) {

        String path = noticeMapper.detailInfo(notice.getModuleKey());
       /* QueryWrapper<Operation> operationQueryWrapper = new QueryWrapper<>();
        operationQueryWrapper.eq("key",notice.getModuleKey());
        operationService.getBaseMapper().select*/
        return path;
    }

    //将状态修改成已读
    public void changeStatus(Page<Notice> noticePage){
        List<Notice> records = noticePage.getRecords();
        //将notice集合封装成一个records的id集合，并筛选出其中的未读的
        List<String> noticeIds = records.stream().filter(record -> {
            if (!record.getStatus()) {
                return true;
            }
            return false;
        }).map(record -> {
            String noticeId = record.getNoticeId();
            return noticeId;
        }).collect(Collectors.toList());
        //将所有的id集合中的记录的状态修改
        UpdateWrapper<Notice> noticeUpdateWrapper = new UpdateWrapper<>();
        noticeUpdateWrapper.in("notice_id",noticeIds).set("status",true);
        this.update(noticeUpdateWrapper);
    }
}
